package cn.linpq.panel;

import cn.linpq.event.MineLabelMouseListenter;
import cn.linpq.frame.MineFrame;
import cn.linpq.label.MineLabel;
import cn.linpq.util.Tools;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.sql.SQLOutput;

/**
 * Desc : 雷区类
 * ClassName : cn.linpq.panel.MineField
 *
 * @author : 林鹏群
 * @date : 2022/12/12 11:33
 */
public class MineField extends JPanel {
    private MineFrame mineFrame;
    private MineLabel[][] mineLabels;
    private MineLabelMouseListenter mineLabelMouseListenter;

    /**
     * 初始化
     */
    public MineField(MineFrame mineFrame) {
        this.mineFrame = mineFrame;
        //设置边框样式[1、内边框凹陷:createLoweredBevelBorder；2、外边框边距5:createEmptyBorder；3、内外边框组合:createCompoundBorder]
        Border borderIn = BorderFactory.createLoweredBevelBorder();
        Border borderOut = BorderFactory.createEmptyBorder(5, 5, 5, 5);
        Border border = BorderFactory.createCompoundBorder(borderOut, borderIn);
        this.setBorder(border);
        //设置背景颜色 Color.lightGray
        this.setBackground(Color.LIGHT_GRAY);
        //设置网格布局
        this.setLayout(new GridLayout(Tools.rows, Tools.cols));
        //初始化雷块[][]
        mineLabels = new MineLabel[Tools.rows][Tools.cols];
        //初始化雷块监听类
        mineLabelMouseListenter = new MineLabelMouseListenter(this);
        //二重循环绑定事件
        for (int i = 0; i < Tools.rows; i++) {
            for (int j = 0; j < Tools.cols; j++) {
                mineLabels[i][j] = new MineLabel(i, j);
                mineLabels[i][j].setIcon(Tools.blank);
                mineLabels[i][j].addMouseListener(mineLabelMouseListenter);
                this.add(mineLabels[i][j]);
            }
        }
    }

    /**
     * 布雷
     */
    public void buildMines(MineLabel mineLabel) {
        for (int i = 0; i < Tools.totalMines; ) {
            int row = (int) (Math.random() * Tools.rows);
            int col = (int) (Math.random() * Tools.cols);
            if (!mineLabels[row][col].isMine() && !mineLabel.equals(mineLabels[row][col])) {
                mineLabels[row][col].setMine(true);
                i++;
            }
        }
        initAroundCounts();
    }

    /**
     * 初始化雷块计数
     */
    public void initAroundCounts() {
        for (int i = 0; i < Tools.rows; i++) {
            for (int j = 0; j < Tools.cols; j++) {

                int aroundCount = 0;
                for (int k = Math.max(0, i - 1); k <= Math.min(i + 1, Tools.rows - 1); k++) {
                    for (int l = Math.max(0, j - 1); l <= Math.min(j + 1, Tools.cols - 1); l++) {
                        if (mineLabels[k][l].isMine()) {
                            aroundCount++;
                        }
                    }
                }
                mineLabels[i][j].setAroundCounts(aroundCount);
            }
        }
    }

    /**
     * 左键打开雷块
     */
    public void openMineLabel(MineLabel mineLabel) {
        if (!mineLabel.isExpand()  && !mineLabel.isFlag()) {
            if (mineLabel.isMine()) {
                System.out.println("失败");
                JOptionPane.showMessageDialog(null,"输了");
                fail(mineLabel);

            } else {
                mineLabel.setIcon(Tools.mineCount[mineLabel.getAroundCounts()]);
                mineLabel.setExpand(true);
                if (mineLabel.getAroundCounts() == 0) {
                    int i = mineLabel.getRow();
                    int j = mineLabel.getCol();
                    for (int k = Math.max(0, i - 1); k <= Math.min(i + 1, Tools.rows - 1); k++) {
                        for (int l = Math.max(0, j - 1); l <= Math.min(j + 1, Tools.cols - 1); l++) {
                            openMineLabel(mineLabels[k][l]);
                        }
                    }

                }
                this.getMineFrame().getMineState().getFace().setIcon(Tools.faces[0]);
                win();
            }
        }
    }

    /**
     * 双键打开雷块
     */
    public void openMineAround(MineLabel mineLabel) {
        if (mineLabel.isExpand() ) {
            int i = mineLabel.getRow();
            int j = mineLabel.getCol();
            int aroundFlag = 0;
            for (int k = Math.max(0, i - 1); k <= Math.min(i + 1, Tools.rows - 1); k++) {
                for (int l = Math.max(0, j - 1); l <= Math.min(j + 1, Tools.cols - 1); l++) {
                    if (mineLabels[k][l].isFlag()) {
                        aroundFlag++;
                    }
                }
            }
            if (mineLabel.getAroundCounts() == aroundFlag) {
                for (int k = Math.max(0, i - 1); k <= Math.min(i + 1, Tools.rows - 1); k++) {
                    for (int l = Math.max(0, j - 1); l <= Math.min(j + 1, Tools.cols - 1); l++) {
                        openMineLabel(mineLabels[k][l]);
                    }
                }
            }else {
                for (int k = Math.max(0, i - 1); k <= Math.min(i + 1, Tools.rows - 1); k++) {
                    for (int l = Math.max(0, j - 1); l <= Math.min(j + 1, Tools.cols - 1); l++) {
                        if(!mineLabels[k][l].isExpand()&&!mineLabels[k][l].isFlag()){
                            mineLabels[k][l].setIcon(Tools.blank);
                        }

                        if(mineLabels[k][l].isMark()){
                            mineLabels[k][l].setIcon(Tools.ask);
                        }
                    }
                }
            }
        }
    }

    /**
     * 胜利
     */
    public void win() {
        int leftMineCount = 0;
        for (int i = 0; i < Tools.rows; i++) {
            for (int j = 0; j < Tools.cols; j++) {
                if (!mineLabels[i][j].isExpand()) {
                    leftMineCount++;
                }
            }
        }
        if (leftMineCount == Tools.totalMines) {
            JOptionPane.showMessageDialog(null,"赢啦");
            for (int i = 0; i < Tools.rows; i++) {
                for (int j = 0; j < Tools.cols; j++) {
                    mineLabels[i][j].removeMouseListener(mineLabelMouseListenter);
                }
            }
            this.getMineFrame().getMineState().getTimer().stop();
            this.getMineFrame().getMineState().getFace().setIcon(Tools.faces[5]);
        }
    }

    /**
     * 失败
     */
    public void fail(MineLabel mineLabel) {
        openAll();
        mineLabel.setIcon(Tools.redMine);
        for (int i = 0; i < Tools.rows; i++) {
            for (int j = 0; j < Tools.cols; j++) {
                mineLabels[i][j].removeMouseListener(mineLabelMouseListenter);
            }
        }
        this.getMineFrame().getMineState().getTimer().stop();
        this.getMineFrame().getMineState().getFace().setIcon(Tools.faces[3]);
    }

    /**
     * 全部展开
     */
    public void openAll() {
        for (int i = 0; i < Tools.rows; i++) {
            for (int j = 0; j < Tools.cols; j++) {


                if (mineLabels[i][j].isMine()) {
                    mineLabels[i][j].setIcon(Tools.mine);
                } else {
                    mineLabels[i][j].setIcon(Tools.mineCount[mineLabels[i][j].getAroundCounts()]);
                }
            }
        }
    }

    public MineFrame getMineFrame() {
        return mineFrame;
    }

    public void setMineFrame(MineFrame mineFrame) {
        this.mineFrame = mineFrame;
    }

    public MineLabel[][] getMineLabels() {
        return mineLabels;
    }

    public void setMineLabels(MineLabel[][] mineLabels) {
        this.mineLabels = mineLabels;
    }

    public MineLabelMouseListenter getMineLabelMouseListenter() {
        return mineLabelMouseListenter;
    }

    public void setMineLabelMouseListenter(MineLabelMouseListenter mineLabelMouseListenter) {
        this.mineLabelMouseListenter = mineLabelMouseListenter;
    }

    public void leftPress(MineLabel source) {
        if (!source.isExpand() && !source.isFlag()) {
            source.leftPress();
            mineFrame.getMineState().getFace().setIcon(Tools.faces[2]);
        }
    }

    public void rightClick(MineLabel source) {
        if (!source.isExpand()){
            source.rightClick();
            int flagCount = 0;
            for (int i = 0; i < Tools.rows; i++) {
                for (int j = 0; j < Tools.cols; j++) {
                    if (mineLabels[i][j].isFlag()) {
                        flagCount++;
                    }
                }
            }
            mineFrame.getMineState().setMineCount(Tools.totalMines-flagCount);
        }

    }

    public void pressMineAround(MineLabel mineLabel) {

        if (mineLabel.isExpand() ) {
            int i = mineLabel.getRow();
            int j = mineLabel.getCol();
            int aroundFlag = 0;
            for (int k = Math.max(0, i - 1); k <= Math.min(i + 1, Tools.rows - 1); k++) {
                for (int l = Math.max(0, j - 1); l <= Math.min(j + 1, Tools.cols - 1); l++) {
                    if(i==k&&j==l){
                        continue;
                    }
                    if(!mineLabels[k][l].isExpand()&&!mineLabels[k][l].isFlag()){
                        mineLabels[k][l].setIcon(Tools.mineCount[0]);
                    }

                    if (mineLabels[k][l].isMark()) {
                        mineLabels[k][l].setIcon(Tools.ask1);
                    }
                }
            }

        }
    }
}
